﻿using System;
using System.Configuration;
using System.Reflection;
using SimpleServiceBus.Configuration;
using SimpleServiceBus.Endpoint;
using SimpleServiceBus.Endpoints.Rhino.Transport;
using SimpleServiceBus.Utilities.ObjectBuilder;

namespace SimpleServiceBus.Endpoints.Rhino.Configuration
{
    public class RhinoConfigurationElement : ConfigurationElement
    {

        [ConfigurationProperty("queueUri",IsRequired=false)]
        public string QueueUri
        {
            get { return (string)base["queueUri"]; }
            set { base["queueUri"] = value; }
        }

        [ConfigurationProperty("inputQueueName", IsRequired = false)]
        public string InputQueueName
        {
            get { return (string)base["inputQueueName"]; }
            set { base["inputQueueName"] = value; }
        }

        [ConfigurationProperty("poisonQueueName", IsRequired = false)]
        public string PoisonQueueName
        {
            get { return (string)base["poisonQueueName"]; }
            set { base["poisonQueueName"] = value; }
        }

        [ConfigurationProperty("queueStoragePath", IsRequired = false)]
        public string QueueStoragePath
        {
            get { return (string)base["queueStoragePath"]; }
            set { base["queueStoragePath"] = value; }
        }
    }

    public class RhinoEndpointConfiguration : EndpointConfiguration
    {
        [ConfigurationProperty("rhino")]
        public RhinoConfigurationElement Rhino
        {
            get { return (RhinoConfigurationElement)base["rhino"]; }
        }


        protected override TransportType ConfigureTransport<TransportType>(IEndpointBuilder endpoint)
        {
            var transport = base.ConfigureTransport<TransportType>(endpoint) as RhinoQueuesTransport;

            if (transport != null)
            {
                if (!String.IsNullOrEmpty(Rhino.QueueUri))
                    transport.QueueUri = new Uri(Rhino.QueueUri);
                else if (!String.IsNullOrEmpty(endpoint.Metadata.ReturnAddress))
                    transport.QueueUri = new Uri(endpoint.Metadata.ReturnAddress);

                if (!String.IsNullOrEmpty(Rhino.InputQueueName))
                    transport.InputQueueName = Rhino.InputQueueName;

                if (!String.IsNullOrEmpty(Rhino.PoisonQueueName))
                    transport.PoisonQueueName = Rhino.PoisonQueueName;

                if (!String.IsNullOrEmpty(Rhino.QueueStoragePath))
                    transport.QueueStoragePath = Rhino.QueueStoragePath;
            }

            return transport as TransportType;
        }

        public static IMessagingEndpoint CreateConfiguredEndpoint(params Assembly[] messageHandlerAssemblies)
        {
            return CreateConfiguredEndpoint(null,messageHandlerAssemblies);
        }

        public static IMessagingEndpoint CreateConfiguredEndpoint(IObjectBuilder IoC,params Assembly[] messageHandlerAssemblies)
        {
            return CreateConfiguredEndpoint<RhinoEndpointBuilder<MessagingEndpoint>, RhinoQueuesTransport>(IoC,messageHandlerAssemblies);
            
        }

        public static IEndpointBuilder ConfigureEndpoint()
        {
            return ConfigureEndpoint(null);
        }

        public static IEndpointBuilder ConfigureEndpoint(IObjectBuilder IoC)
        {
            return ConfigureEndpoint<RhinoEndpointBuilder<MessagingEndpoint>, RhinoQueuesTransport>();
        }
    }
}